package com.bjpowernode.boss.web.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bjpowernode.boss.constants.Constant;
import com.bjpowernode.boss.dao.domain.PmsOperator;
import com.bjpowernode.boss.dao.mapper.PmsOperatorMapper;
import com.bjpowernode.boss.enums.RespCode;
import com.bjpowernode.boss.exceptions.BossException;
import com.bjpowernode.boss.util.JWTUtil;
import com.bjpowernode.boss.util.RedisClient;
import com.bjpowernode.boss.web.dto.LoginResultDto;
import com.bjpowernode.boss.web.model.query.LoginQuery;
import com.bjpowernode.boss.web.service.OperatorService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

//校验登录，并存token的
@Service
public class OperatorServiceImpl implements OperatorService {
    @Resource
    private RedisClient redisClient;

    @Resource
    private PmsOperatorMapper operatorMapper;
    //synchronized同步，避免同时多个登录请求进入
    @Override
    public synchronized LoginResultDto login(LoginQuery loginQuery) {
        //使用loginName查询数据库
        QueryWrapper<PmsOperator> wrapper = new QueryWrapper<>();
        wrapper.eq("login_name", loginQuery.getLoginName());
        PmsOperator pmsOperator = operatorMapper.selectOne(wrapper);
        //为空，即表里没有此时登录的用户，则登录失败
        if (pmsOperator == null){
            throw new BossException(RespCode.LOGIN_NAME_PWD_ERROR);

        }
        //若不为空则执行以下
        //获取salt（盐值），比较密码,因为前端发来的值是加密过的
        String salt = pmsOperator.getSalt();
        //根据前端提交的密码+salt（盐值）使用md5计算出一个密码与数据库中的密码进行对比
        String newLoginPwd = DigestUtil.md5Hex(loginQuery.getLoginPwd() + salt);
        //比较,密码错位抛出异常
        if (!newLoginPwd.equals(pmsOperator.getLoginPwd())){
            throw new BossException(RespCode.LOGIN_NAME_PWD_ERROR);
        }
        //密码正确则生成token，存储，并返回数据给前端


        //生成token，带有有效时间
        //hutool工具库JSONObject，将数据转为json格式
        JSONObject json = new JSONObject();
        json.set("loginId", pmsOperator.getId());
        String jwt = JWTUtil.createJWT(json.toString(), 120);


        //存储token，需要redis工具类
        //redis工具类中使用hash存储，因此需要把token放入map
        Map<String ,String> hashData = new HashMap<>();
        hashData.put( "loginId",String.valueOf(pmsOperator.getId()));
        hashData.put("jwt",jwt);
        //登陆时间需要格式，因此new SimpleDateFormat格式化日期
        hashData.put("loginTime",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //放入对象
        String OperatorKey = Constant.OPERATOR_JWT+pmsOperator.getId();
        boolean save = redisClient.addAllHash(OperatorKey,hashData,120, TimeUnit.MINUTES);
        if (!save){
            throw new BossException(RespCode.LOGIN_INTERNVAL_ERROR);
        }
        //返回数据给前端
        return new LoginResultDto(pmsOperator.getId(),pmsOperator.getShowName(),jwt);
    }
}
